﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Godot.core.io
{
    using SysMethodInfo = System.Reflection.MethodInfo;

    public partial class XMLParser : Reference
    {
        public enum NodeType 
        {
		    NODE_NONE,
		    NODE_ELEMENT,
		    NODE_ELEMENT_END,
		    NODE_TEXT,
		    NODE_COMMENT,
		    NODE_CDATA,
		    NODE_UNKNOWN
	    };

        public Error read()
        {
            throw new System.NotImplementedException();
        }

	    public NodeType get_node_type()
        {
            throw new System.NotImplementedException();
        }

	    public string get_node_name()
        {
            throw new System.NotImplementedException();
        }

	    public string get_node_data()
        {
            throw new System.NotImplementedException();
        }

	    public ulong get_node_offset()
        {
            throw new System.NotImplementedException();
        }

	    public int get_attribute_count()
        {
            throw new System.NotImplementedException();
        }

	    public string get_attribute_name(int p_idx)
        {
            throw new System.NotImplementedException();
        }

	    public string get_attribute_value(int p_idx)
        {
            throw new System.NotImplementedException();
        }

        public string get_indexed_attribute_value(int p_idx)
        {
            return get_attribute_value(p_idx);
        }

	    public bool has_attribute(string p_name)
        {
            throw new System.NotImplementedException();
        }

	    public string get_attribute_value(string p_name)
        {
            throw new System.NotImplementedException();
        }

        public string get_named_attribute_value(string p_name)
        {
            return get_attribute_value(p_name);
        }

	    public string get_attribute_value_safe(string p_name) // do not print error if doesn't exist
        {
            throw new System.NotImplementedException();
        }

	    public bool is_empty()
        {
            throw new System.NotImplementedException();
        }

	    public int get_current_line()
        {
            throw new System.NotImplementedException();
        }

	    public void skip_section()
        {
            throw new System.NotImplementedException();
        }

	    public Error seek(ulong p_pos)
        {
            throw new System.NotImplementedException();
        }

	    public Error open(string p_path)
        {
            throw new System.NotImplementedException();
        }

	    public Error open_buffer(List<byte> p_buffer)
        {
            throw new System.NotImplementedException();
        }

	    public void close()
        {
            throw new System.NotImplementedException();
        }

        protected static new void _bind_methods() 
        {
	        ObjectTypeDB.bind_method(_MD("read"),typeof(XMLParser).GetMethod("read", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("get_node_type"),typeof(XMLParser).GetMethod("get_node_type", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("get_node_name"),typeof(XMLParser).GetMethod("get_node_name", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("get_node_data"),typeof(XMLParser).GetMethod("get_node_data", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("get_node_offset"),typeof(XMLParser).GetMethod("get_node_offset", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("get_attribute_count"),typeof(XMLParser).GetMethod("get_attribute_count", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("get_attribute_name"),typeof(XMLParser).GetMethod("get_attribute_name", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("get_attribute_value"),typeof(XMLParser).GetMethod("get_indexed_attribute_value", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("has_attribute"),typeof(XMLParser).GetMethod("has_attribute", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("get_named_attribute_value"), typeof(XMLParser).GetMethod("get_named_attribute_value", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("get_named_attribute_value_safe"), typeof(XMLParser).GetMethod("get_attribute_value_safe", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("is_empty"),typeof(XMLParser).GetMethod("is_empty", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("get_current_line"),typeof(XMLParser).GetMethod("get_current_line", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("skip_section"),typeof(XMLParser).GetMethod("skip_section", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("seek"),typeof(XMLParser).GetMethod("seek", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("open","file"),typeof(XMLParser).GetMethod("open", Misc.BindingFlags_Greedy));
	        ObjectTypeDB.bind_method(_MD("open_buffer","buffer"),typeof(XMLParser).GetMethod("open_buffer", Misc.BindingFlags_Greedy));

            ObjectTypeDB.bind_integer_constant(get_type_static(), "NODE_NONE", (int)NodeType.NODE_NONE);
            ObjectTypeDB.bind_integer_constant(get_type_static(), "NODE_ELEMENT", (int)NodeType.NODE_ELEMENT);
            ObjectTypeDB.bind_integer_constant(get_type_static(), "NODE_ELEMENT_END", (int)NodeType.NODE_ELEMENT_END);
            ObjectTypeDB.bind_integer_constant(get_type_static(), "NODE_TEXT", (int)NodeType.NODE_TEXT);
            ObjectTypeDB.bind_integer_constant(get_type_static(), "NODE_COMMENT", (int)NodeType.NODE_COMMENT);
            ObjectTypeDB.bind_integer_constant(get_type_static(), "NODE_CDATA", (int)NodeType.NODE_CDATA);
            ObjectTypeDB.bind_integer_constant(get_type_static(), "NODE_UNKNOWN", (int)NodeType.NODE_UNKNOWN);
        }
    }

    public partial class XMLParser
    {
        #region OBJ_TYPE( XMLParser, Reference )
        public override string get_type() { return "XMLParser"; }

        public override string get_save_type() { return get_type(); } //type stored when saving

        public override StringName get_type_name() { return (StringName)get_type_static(); }

        public override bool is_type(string p_type) { return (p_type == "XMLParser") ? true : base.is_type(p_type); }

        protected override void _initialize_typev() { initialize_type(); }

        protected override bool _setv(StringName p_name, Variant p_property)
        {
            if (base._setv(p_name, p_property))
                return true;

            if (typeof(XMLParser).GetMethod("_set", Misc.BindingFlags_Greedy) != typeof(Reference).GetMethod("_set", Misc.BindingFlags_Greedy))
            {
                return _set(p_name, p_property);
            }

            return false;
        }

        protected override bool _getv(StringName p_name, ref Variant r_property)
        {
            if (typeof(XMLParser).GetMethod("_get", Misc.BindingFlags_Greedy) != typeof(Reference).GetMethod("_get", Misc.BindingFlags_Greedy))
            {
                if (_get(p_name, ref r_property))
                    return true;
            }

            return base._getv(p_name, ref r_property);
        }

        protected override void _get_property_listv(ref List<PropertyInfo> p_list, bool p_reversed)
        {
            if (!p_reversed)
            {
                base._get_property_listv(ref p_list, p_reversed);
            }

            p_list.Add(new PropertyInfo(Variant.Type.NIL, get_type_static(), PropertyHint.PROPERTY_HINT_NONE, "", (int)PropertyUsageFlags.PROPERTY_USAGE_CATEGORY));

            if (!_is_gpl_reversed())
                ObjectTypeDB.get_property_list("XMLParser", ref p_list, true);

            if (typeof(XMLParser).GetMethod("_get_property_list", Misc.BindingFlags_Greedy) != typeof(Reference).GetMethod("_get_property_list", Misc.BindingFlags_Greedy))
            {
                _get_property_list(ref p_list);
            }

            if (_is_gpl_reversed())
                ObjectTypeDB.get_property_list("XMLParser", ref p_list, true);

            if (p_reversed)
            {
                base._get_property_listv(ref p_list, p_reversed);
            }
        }

        protected override void _notificationv(int p_notification, bool p_reversed)
        {
            if (!p_reversed)
                base._notificationv(p_notification, p_reversed);

            if (typeof(XMLParser).GetMethod("_notification", Misc.BindingFlags_Greedy) != typeof(Reference).GetMethod("_notification", Misc.BindingFlags_Greedy))
            {
                _notification(p_notification);
            }

            if (p_reversed)
                base._notificationv(p_notification, p_reversed);
        }

        public static new string get_type_static() { return "XMLParser"; }

        public static new string get_parent_type_static() { return Reference.get_type_static(); }

        public static new void get_inheritance_list_static(ref List<string> r_inheritance_list)
        {
            Reference.get_inheritance_list_static(ref r_inheritance_list);
            r_inheritance_list.Add(get_type_static());
        }

        public static new string get_category_static()
        {
            string category = Reference.get_category_static();
            if (typeof(XMLParser).GetMethod("_get_category", Misc.BindingFlags_Greedy) != typeof(Reference).GetMethod("_get_category", Misc.BindingFlags_Greedy))
            {
                if (category != "")
                    category += "/";
                category += _get_category();
            }
            return category;
        }

        public static new string inherits_static() { return "Reference"; }

        public static new void get_valid_parents_static(ref List<string> p_parents)
        {
            if (typeof(XMLParser).GetMethod("_get_valid_parents_static", Misc.BindingFlags_Greedy) != typeof(Reference).GetMethod("_get_valid_parents_static", Misc.BindingFlags_Greedy))
            {
                XMLParser._get_valid_parents_static(ref p_parents);
            }

            Reference.get_valid_parents_static(ref p_parents);
        }

        public static new void initialize_type()
        {
            if (__initialized)
                return;
            Reference.initialize_type();
            ObjectTypeDB._add_type<XMLParser>();

            SysMethodInfo cls_bind = typeof(XMLParser).GetMethod("_bind_methods", Misc.BindingFlags_Greedy);
            SysMethodInfo par_bind = typeof(Reference).GetMethod("_bind_methods", Misc.BindingFlags_Greedy);
            if (cls_bind != par_bind)
                cls_bind.Invoke(null, null);
            __initialized = true;
        }

        private static bool __initialized = false;
        #endregion
    }
}
